package cn.com.acca.ma.service.impl;

import cn.com.acca.ma.common.util.DateUtil;
import cn.com.acca.ma.common.util.PropertiesUtil;
import cn.com.acca.ma.model.Board;
import cn.com.acca.ma.model.Model;
import cn.com.acca.ma.model.ModelTopStockDetail;
import cn.com.acca.ma.service.ModelTopStockDetailService;
import cn.com.acca.ma.service.ModelTopStockService;

import java.awt.*;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.time.Day;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.ui.RectangleInsets;

public class ModelTopStockDetailServiceImpl extends BaseServiceImpl<ModelTopStockDetailServiceImpl, ModelTopStockDetail> implements
        ModelTopStockDetailService {

    /*********************************************************************************************************************
     *
     * 												按日期计算数据
     *
     *********************************************************************************************************************/
    /**
     * 按照日期，向表MDL_TOP_STOCK_DETAIL中写入数据
     *
     * @param multithreading
     */
    @Override
    public void writeModelTopStockDetailByDate(boolean multithreading) {
        String beginDate = PropertiesUtil.getValue(MODEL_TOP_STOCK_DETAIL_PROPERTIES, "top.stock.detail.begin_date");
        String endDate = PropertiesUtil.getValue(MODEL_TOP_STOCK_DETAIL_PROPERTIES, "top.stock.detail.end_date");
        modelTopStockDetailDao.writeModelTopStockDetailByDate(multithreading, beginDate, endDate);
    }

    /**
     * 根据开始日期beginDate和结束日期endDate计算表MDL_TOP_STOCK_DETAIL中的percentage_*_ma*字段
     */
    @Override
    public void writeModelTopStockDetailMAByDate() {
        String beginDate = PropertiesUtil.getValue(MODEL_TOP_STOCK_DETAIL_PROPERTIES, "top.stock.detail.ma.begin_date");
        String endDate = PropertiesUtil.getValue(MODEL_TOP_STOCK_DETAIL_PROPERTIES, "top.stock.detail.ma.end_date");
        modelTopStockDetailDao.writeModelTopStockDetailMAByDate(beginDate, endDate);
    }


    /*********************************************************************************************************************
     *
     * 												创建图表
     *
     *********************************************************************************************************************/
    /**
     * 按照日期，创建每支股票上涨百分比的折线图
     */
    @Override
    public void createModelTopStockDetailPicture() {
        String beginDate = PropertiesUtil.getValue(MODEL_TOP_STOCK_DETAIL_PICTURE_PROPERTIES, "top.stock.detail.picture.begin_date");
        String endDate = PropertiesUtil.getValue(MODEL_TOP_STOCK_DETAIL_PICTURE_PROPERTIES, "top.stock.detail.picture.end_date");

        TimeSeriesCollection timeSeriesCollection = new TimeSeriesCollection();
        TimeSeries upDownPercentage21TimeSeries = new TimeSeries("up_down_percentage_21平均值", org.jfree.data.time.Day.class);
        TimeSeries percentage21Ma5TimeSeries = new TimeSeries("percentage_21_ma5平均值", org.jfree.data.time.Day.class);
        TimeSeries percentage21Ma10TimeSeries = new TimeSeries("percentage_21_ma10平均值", org.jfree.data.time.Day.class);
        TimeSeries percentage21Ma20TimeSeries = new TimeSeries("percentage_21_ma20平均值", org.jfree.data.time.Day.class);
        TimeSeries avgClosePriceTimeSeries = new TimeSeries("close_price平均值", org.jfree.data.time.Day.class);

        // 获取数据
        List<Object> list = modelTopStockDetailDao.findDateAndAvgBetweenGroupByOrderBy(beginDate, endDate);
        List<Object> maxMinAverageCloseList = stockTransactionDataDao.getMaxMinAverageCloseWeek(false, beginDate, endDate);
        BigDecimal maxAvgClosePrice = (BigDecimal) ((Object[]) maxMinAverageCloseList.get(0))[0];
        BigDecimal minAvgClosePrice = (BigDecimal) ((Object[]) maxMinAverageCloseList.get(0))[1];
        List<Object> upDownPercentage21List = modelTopStockDetailDao.getMaxMinAverageUpDownPercentage21Week(false, beginDate, endDate);
        BigDecimal maxUpDownPercentage21 = (BigDecimal) ((Object[]) upDownPercentage21List.get(0))[0];
        BigDecimal minUpDownPercentage21 = (BigDecimal) ((Object[]) upDownPercentage21List.get(0))[1];
        for (int i = 0; i < list.size(); i++) {
            Object[] objectArray = (Object[]) list.get(i);
            Date date = (Date) objectArray[0];
            int year = DateUtil.getYearFromDate(date);
            int month = DateUtil.getMonthFromDate(date);
            int day = DateUtil.getDateFromDate(date);
            BigDecimal upDownPercentage21 = (BigDecimal) objectArray[1];
            if (null != upDownPercentage21){
                upDownPercentage21TimeSeries.add(new Day(day, month, year), upDownPercentage21.doubleValue());
            } else {
                upDownPercentage21TimeSeries.add(new Day(day, month, year), null);
            }
        }
        timeSeriesCollection.addSeries(upDownPercentage21TimeSeries);
        for (int i = 0; i < list.size(); i++) {
            Object[] objectArray = (Object[]) list.get(i);
            Date date = (Date) objectArray[0];
            int year = DateUtil.getYearFromDate(date);
            int month = DateUtil.getMonthFromDate(date);
            int day = DateUtil.getDateFromDate(date);
            BigDecimal percentage21Ma5 = (BigDecimal) objectArray[2];
            if (null != percentage21Ma5){
                percentage21Ma5TimeSeries.add(new Day(day, month, year), percentage21Ma5.doubleValue());
            } else {
                percentage21Ma5TimeSeries.add(new Day(day, month, year), null);
            }
        }
        timeSeriesCollection.addSeries(percentage21Ma5TimeSeries);
        for (int i = 0; i < list.size(); i++) {
            Object[] objectArray = (Object[]) list.get(i);
            Date date = (Date) objectArray[0];
            int year = DateUtil.getYearFromDate(date);
            int month = DateUtil.getMonthFromDate(date);
            int day = DateUtil.getDateFromDate(date);
            BigDecimal percentage21Ma10 = (BigDecimal) objectArray[3];
            if (null != percentage21Ma10){
                percentage21Ma10TimeSeries.add(new Day(day, month, year), percentage21Ma10.doubleValue());
            } else {
                percentage21Ma10TimeSeries.add(new Day(day, month, year), null);
            }
        }
        timeSeriesCollection.addSeries(percentage21Ma10TimeSeries);
        for (int i = 0; i < list.size(); i++) {
            Object[] objectArray = (Object[]) list.get(i);
            Date date = (Date) objectArray[0];
            int year = DateUtil.getYearFromDate(date);
            int month = DateUtil.getMonthFromDate(date);
            int day = DateUtil.getDateFromDate(date);
            BigDecimal percentage21Ma20 = (BigDecimal) objectArray[4];
            if (null != percentage21Ma20){
                percentage21Ma20TimeSeries.add(new Day(day, month, year), percentage21Ma20.doubleValue());
            } else {
                percentage21Ma20TimeSeries.add(new Day(day, month, year), null);
            }
        }
        timeSeriesCollection.addSeries(percentage21Ma20TimeSeries);
        for (int i = 0; i < list.size(); i++) {
            Object[] objectArray = (Object[]) list.get(i);
            Date date = (Date) objectArray[0];
            int year = DateUtil.getYearFromDate(date);
            int month = DateUtil.getMonthFromDate(date);
            int day = DateUtil.getDateFromDate(date);
            BigDecimal avgClosePrice = (BigDecimal) objectArray[5];
            if (null != avgClosePrice){
                avgClosePriceTimeSeries.add(new Day(day, month, year), this.adjustData(maxAvgClosePrice.doubleValue(), minAvgClosePrice.doubleValue(), maxUpDownPercentage21.doubleValue(), minUpDownPercentage21.doubleValue(), avgClosePrice.doubleValue()));
            } else {
                avgClosePriceTimeSeries.add(new Day(day, month, year), null);
            }
        }
        timeSeriesCollection.addSeries(avgClosePriceTimeSeries);

        // 配置字体
        // X轴字体
        Font xFont = new Font("宋体", Font.PLAIN, 40);
        // Y轴字体
        Font yFont = new Font("宋体", Font.PLAIN, 40);
        // 底部字体
        Font bottomFont = new Font("宋体", Font.PLAIN, 40);
        // 图片标题字体
        Font titleFont = new Font("隶书", Font.BOLD, 50);

        JFreeChart jfreechart = ChartFactory.createTimeSeriesChart("Model Top Stock Detail",
                "日期", "平均值", timeSeriesCollection, true, true, true);

        jfreechart.setBackgroundPaint(Color.white);
        // 图片标题
        jfreechart.setTitle(new TextTitle(jfreechart.getTitle().getText(), titleFont));
        // 底部字体
        jfreechart.getLegend().setItemFont(bottomFont);

        XYPlot xyPlot = (XYPlot) jfreechart.getPlot();
        xyPlot.setBackgroundPaint(Color.lightGray);
        xyPlot.setDomainGridlinePaint(Color.white);
        xyPlot.setRangeGridlinePaint(Color.white);
        xyPlot.setAxisOffset(new RectangleInsets(5D, 5D, 5D, 5D));
        xyPlot.setDomainCrosshairVisible(true);
        xyPlot.setRangeCrosshairVisible(true);
        xyPlot.getDomainAxis();

        // X轴
        ValueAxis domainAxis = xyPlot.getDomainAxis();
        // X轴标题字体
        domainAxis.setLabelFont(xFont);
        // Y轴
        ValueAxis rangeAxis = xyPlot.getRangeAxis();
        // Y轴标题字体
        rangeAxis.setLabelFont(yFont);

        org.jfree.chart.renderer.xy.XYItemRenderer xyItemRenderer = xyPlot.getRenderer();
        // 设置所有线条粗细
        xyItemRenderer.setStroke(new BasicStroke(5.0F));
        if (xyItemRenderer instanceof XYLineAndShapeRenderer) {
            XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer) xyItemRenderer;
            xylineandshaperenderer.setBaseShapesVisible(true);
            xylineandshaperenderer.setBaseShapesFilled(true);
            xylineandshaperenderer.setSeriesPaint(2, Color.BLACK);
        }
        DateAxis dateaxis = (DateAxis) xyPlot.getDomainAxis();
        dateaxis.setDateFormatOverride(new SimpleDateFormat("yyyy-MM-dd"));

        try {
            FileOutputStream fos = new FileOutputStream(PICTURE_PATH + "top_stock_detail/" + beginDate + "-" + endDate + PICTURE_FORMAT);
            // 将统计图标输出成JPG文件
            ChartUtilities.writeChartAsJPEG(fos, // 输出到哪个输出流
                    1, // JPEG图片的质量，0~1之间
                    jfreechart, // 统计图标对象
                    1800, // 宽
                    1000,// 宽
                    null // ChartRenderingInfo 信息
            );
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public String listToString(List list) {
        return null;
    }


}
